package com.tkjt.pms.persist.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tkjt.pms.calc.common.DepartOwner;
import com.tkjt.pms.calc.common.NodeDepenChains;
import com.tkjt.pms.common.entity.TkIndexTree;
import com.tkjt.pms.modules.common.mapper.TkIndexTreeMapper;
import com.tkjt.pms.persist.dao.IndexCalcDao;
import com.tkjt.pms.persist.mapper.PmsMapper;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Transactional
@Repository("indexCalcDao")
public class IndexCalcDaoImpl implements IndexCalcDao {

	@Autowired
	private TkIndexTreeMapper tkIndexTreeMapper;
	@Autowired
	private PmsMapper pmsMapper;

	@Override
	public LinkedList<String> loadNodeLevelChain(String nodeType, String indexYearMonth, String indexGroup, String nodeCode) {

		LinkedList<String> results = new LinkedList<>();
		results.add(nodeCode);
		log.info("load index value level chain, start...");

		nodeType = nodeType.substring(0, 2) + "Level";

		while (true) {
			QueryWrapper<TkIndexTree> queryWrapper = new QueryWrapper<>();
			queryWrapper.lambda().eq(TkIndexTree::getNodeType, nodeType);
			queryWrapper.lambda().eq(TkIndexTree::getIndexGroup, indexGroup);
			queryWrapper.lambda().eq(TkIndexTree::getNodeCodeChild, results.getFirst());
			TkIndexTree entity = tkIndexTreeMapper.selectOne(queryWrapper);
			if (null == entity) {
				// 若ivLevel中没有配置数据项指标，则该数据项目不参考与计算
				// 若dpLevel中没有配置部门编码，则该部门不参考与计算
				// 如果该节点没有上级节点，则检查该节是否已在计算层级表中配置，没配置则不参考计算
				queryWrapper = new QueryWrapper<>();
				queryWrapper.lambda().eq(TkIndexTree::getNodeType, nodeType);
				queryWrapper.lambda().eq(TkIndexTree::getIndexGroup, indexGroup);
				queryWrapper.lambda().eq(TkIndexTree::getNodeCode, results.getFirst());
				Integer count = tkIndexTreeMapper.selectCount(queryWrapper);
				if (count <= 0) {
					results.remove(results.getFirst());
				}
				break;
			}
			results.addFirst(entity.getNodeCode());
		}
		log.info("load index value level chain, end.");

		return results;
	}

	@Override
	public NodeDepenChains loadNodeDepenChains(String nodeType, String indexYearMonth, String indexGroup, Set<String> nodeCodeCodes) {

		NodeDepenChains results = new NodeDepenChains();

		nodeType = nodeType.substring(0, 2) + "Depen";

		Set<String> lastSearchDependCodes = new HashSet<String>();
		Set<String> needSearchDependCodes = new HashSet<String>(nodeCodeCodes);
		log.info("load index value depen chain, start...");
		while (true) {
			QueryWrapper<TkIndexTree> queryWrapper = new QueryWrapper<>();
			queryWrapper.lambda().eq(TkIndexTree::getNodeType, nodeType);
			queryWrapper.lambda().eq(TkIndexTree::getIndexGroup, indexGroup);
			queryWrapper.lambda().in(TkIndexTree::getNodeCodeChild, needSearchDependCodes);
			List<TkIndexTree> tempEntities = tkIndexTreeMapper.selectList(queryWrapper);
			lastSearchDependCodes.addAll(needSearchDependCodes);
			// 若不存在dependency chain
			if (CollectionUtils.isEmpty(tempEntities)) {
				break;
			}
			for (TkIndexTree item : tempEntities) {
				LinkedList<String> oneDepenList = this.loadNodeLevelChain(nodeType, indexYearMonth, indexGroup, item.getNodeCode());
				if (null != oneDepenList) {
					results.addOneDepenChain(item.getNodeCodeChild(), oneDepenList);
					needSearchDependCodes.addAll(oneDepenList);
				} else {
					// needSearchDependCodes.add(item.getNodeCode());
				}
			}
			// 删除已查找过的dependency chain codes
			needSearchDependCodes.removeAll(lastSearchDependCodes);
			// 若所有节点的dependency chain已查找完毕，则结束循环
			if (needSearchDependCodes.isEmpty()) {
				break;
			}
		}
		log.info("load index value depen chain, end.");

		return results;

	}

	@Override
	public Map<String, Set<DepartOwner>> loadDepartOwnersByIndexDeparts(Set<String> indexDeparts) {
		Map<String, Set<DepartOwner>> results = new HashMap<String, Set<DepartOwner>>();
		List<DepartOwner> departOwners = pmsMapper.getDepartOwnerByCodes(indexDeparts);
		for (DepartOwner item : departOwners) {

			Set<DepartOwner> tempSet = results.get(item.getIndexDepart());
			if (null == tempSet) {
				tempSet = new HashSet<DepartOwner>();
				results.put(item.getIndexDepart(), tempSet);
			}
			tempSet.add(item);

		}
		return results;
	}

	@Override
	public Set<String> loadIndexValueCodeLeafs(String indexGroup) {
		Set<String> results = new HashSet<String>();
		List<String> queryResults = pmsMapper.getIndexValueCodeLeafs(indexGroup);
		results.addAll(queryResults);
		return results;

	}

	@Override
	public Set<String> loadDepartLeafs(String indexGroup) {
		Set<String> results = new HashSet<String>();
		String queryIndexGroup = "";
		if ("C".equals(indexGroup)) {
			queryIndexGroup = "A01A01A01A";
		} else if ("G".equals(indexGroup)) {
			queryIndexGroup = "A01A01A02A";
		}
		List<String> queryResults = pmsMapper.getDepartLeafs(queryIndexGroup);
		results.addAll(queryResults);
		return results;
	}

	@Override
	public List<String> loadIndexGroupOrder(Set<String> indexGroups) {
		List<String> orders = new ArrayList<String>();
		orders.add("C");
		orders.add("G");
		return orders;
	}

}
